/**
  ******************************************************************************
  * @file    sym32l010_hal_i2c.h
  * @author  AE Team
  * @version 1.0.3
  * @date    2024-05-28
  * @brief   Header file of I2C HAL module.
  *
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2024 SIYIMicro.
  * All rights reserved.</center></h2>
  *
  *
  ******************************************************************************
  */


/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __SYM32L010_HAL_I2C_H
#define __SYM32L010_HAL_I2C_H

#ifdef __cplusplus
extern "C" {
#endif


/******************************************************************************/
/* Include files                                                              */
/******************************************************************************/
#include "sym32l010_hal_def.h"


/******************************************************************************/
/* Global type definitions                                                    */
/******************************************************************************/
/* I2C 主从模式 --------------------------------------------------------------*/
typedef enum
{
    I2C_WORKMODE_MASTER        = (1UL),                               // 主机模式
    I2C_WORKMODE_SLAVE         = (0UL)                                // 从机模式
} I2C_WorkModeTypeDef;

/* I2C SDA 输入信号来源 -------------------------------------------------------*/
typedef enum
{
    I2C_SDAINSRC_GPIO          = (0x0UL << I2Cx_CR_SDAINSRC_Pos),     // GPIO管脚
    I2C_SDAINSRC_VC1_OUT       = (0x1UL << I2Cx_CR_SDAINSRC_Pos),     // VC1_OUT
    I2C_SDAINSRC_VC2_OUT       = (0x2UL << I2Cx_CR_SDAINSRC_Pos)      // VC2_OUT
} I2C_SdaInSrcTypeDef;

/* I2C SCL 输入信号来源 -------------------------------------------------------*/
typedef enum
{
    I2C_SCLINSRC_GPIO          = (0x0UL << I2Cx_CR_SCLINSRC_Pos),     // GPIO管脚
    I2C_SCLINSRC_VC1_OUT       = (0x1UL << I2Cx_CR_SCLINSRC_Pos),     // VC1_OUT
    I2C_SCLINSRC_VC2_OUT       = (0x2UL << I2Cx_CR_SCLINSRC_Pos)      // VC2_OUT
} I2C_SclInSrcTypeDef;

/* I2C 应答方式 ---------------------------------------------------------------*/
typedef enum
{
    I2C_RESPONSE_ACK           = (0x1UL << I2Cx_CR_AA_Pos),
    I2C_RESPONSE_NAK           = (0x0UL << I2Cx_CR_AA_Pos)
} I2C_ResponseTypeDef;

/* I2C 传输方向 ---------------------------------------------------------------*/
typedef enum
{
    I2C_XFERMODE_TRANSMIT      = (0UL),
    I2C_XFERMODE_RECEIVE       = (1UL)
} I2C_XferModeTypeDef;

/* I2C 主机传输完成后的动作 ---------------------------------------------------*/
typedef enum
{
    I2C_XFERDONE_STOP          = (0UL),
    I2C_XFERDONE_NONE          = (1UL)
} I2C_XferDoneTypeDef;

/* I2C 错误码 -----------------------------------------------------------------*/
typedef enum
{
    // 通用错误码
    I2C_ERROR_OK                            = (0x00UL),               // 正常运行
    I2C_ERROR_BUS                           = (0x01UL),               // 总线错误

    // 主机错误码
    I2C_ERROR_SENDSTART_TIMEOUT             = (0x02UL),               // 发送Start时超时
    I2C_ERROR_MASTER_TRANSMIT_TIMEOUT       = (0x03UL),               // 发送数据时超时
    I2C_ERROR_MASTER_RECEIVE_TIMEOUT        = (0x04UL),               // 接收数据时超时
    I2C_ERROR_MASTER_TRANSMIT_DATA_REMAIN   = (0x05UL),               // 发送数据时剩余
    I2C_ERROR_MASTER_SENDADDR_NACK          = (0x06UL),               // 发送地址无设备应答
    I2C_ERROR_MASTER_STATUS                 = (0x07UL),               // 状态机错误
    I2C_ERROR_MASTER_LOS_ARB                = (0x08UL),               // 丢失仲裁
    I2C_ERROR_MASTER_LOS_ARB_S              = (0x09UL),               // 丢失仲裁同时作为从机已应答自身地址

    // 从机错误码
    I2C_ERROR_SLAVE_TRANSMIT_TIMEOUT        = (0x21UL),               // 发送时超时
    I2C_ERROR_SLAVE_RECEIVE_TIMEOUT         = (0x22UL),               // 接收时超时
    I2C_ERROR_SLAVE_STATUS                  = (0x23UL),               // 状态机错误
    I2C_ERROR_SLAVE_TRANSMIT_DATA_REMAIN    = (0x24UL),               // 发送数据时剩余
    I2C_ERROR_SLAVE_TRANSMIT_DATA_OV        = (0x25UL),               // 发送数据时溢出
    I2C_ERROR_SLAVE_RECEIVE_DATA_REMAIN     = (0x26UL),               // 接收数据时剩余
    I2C_ERROR_SLAVE_RECEIVE_RESTART         = (0x27UL)                // 接收数据时收到起始或停止信号
} I2C_ErrorTypeDef;

/* I2C 初始化结构体 -----------------------------------------------------------*/
typedef struct
{
    uint8_t                      OwnAddr0;                            // 自身地址0，b7-b1
    uint8_t                      OwnAddr1;                            // 自身地址1，b7-b1
    uint8_t                      OwnAddr2;                            // 自身地址2，b7-b1
    uint32_t                     PclkFreq;                            // PCLK频率，以Hz为单位
    uint32_t                     SclFreq;                             // SCL频率，以Hz为单位
    I2C_SclInSrcTypeDef          SclInSrc;                            // SCL 输入来源 管脚,VC_OUT
    I2C_SdaInSrcTypeDef          SdaInSrc;                            // SDA 输入来源 管脚,VC_OUT
    FunctionalState              GeneralCall;                         // 广播呼叫，ENABLE / DISABLE
    I2C_WorkModeTypeDef          WorkMode;                            // I2C_MODE_Master / I2C_MODE_Slave
} I2C_InitTypeDef;

/* ---------------------------------------------------------------------------*/
typedef struct
{
    I2C_TypeDef                  *Instance;                           // I2C 实体
    I2C_InitTypeDef              Init;                                // I2C 初始化结构体

    __IO uint8_t                 DevAddress;                          // I2C 目标设备地址
    __IO uint32_t                MemAddress;                          // I2C 目标设备存储地址
    __IO uint32_t                MemAddrSize;                         // I2C 目标设备存储地址大小（以字节计算）

    uint8_t                      *pBuffPtr;                           // I2C 待输数据的指针
    __IO uint32_t                XferCount;                           // I2C 当前剩余待传输的数据帧数
    uint32_t                     XferSize;                            // I2C 待传输的数据帧数
    I2C_XferModeTypeDef          XferMode;                            // I2C 传输模式 XFERMODE_TRANSMIT / I2C_XFERMODE_RECEIVE
    I2C_XferDoneTypeDef          XferDone;                            // I2C 传输结束后的动作 I2C_XFERDONE_STOP    : 传输完成后发送Stop
                                                                      //                      I2C_XFERDONE_CONTINUE: 传输完成后不发Stop
    __IO HAL_StatusTypeDef       XferState;                           // I2C 传输状态 HAL_BUSY / HAL_ERROR / HAL_TIMEOUT / HAL_OK
    __IO I2C_ErrorTypeDef        ErrorCode;                           // I2C 错误码
} I2C_HandleTypeDef;


/******************************************************************************/
/* Global pre-processor symbols/macros ('#define')                            */
/******************************************************************************/
/* I2C 访问地址 ---------------------------------------------------------------*/
#define I2C_AccessAddr_0                (1UL)
#define I2C_AccessAddr_1                (2UL)
#define I2C_AccessAddr_2                (4UL)
#define I2C_AccessAddr_GC               (8UL)


/******************************************************************************/
/* Global macro function                                                      */
/******************************************************************************/
/**
  * @brief  获取 I2C 中断标志
  * @param  HANDLE : I2C 句柄指针，指向包含I2C配置、通信参数的结构体
  * @retval
  */
#define HAL_I2C_GET_FLAG(HANDLE)  ((HANDLE)->Instance->CR & I2Cx_CR_SI_Msk)

/**
  * @brief  清除 I2C 中断标志
  * @param  HANDLE : I2C 句柄指针，指向包含I2C配置、通信参数的结构体
  * @retval
  */
#define HAL_I2C_CLR_FLAG(HANDLE)  ((HANDLE)->Instance->CR &= ~(I2Cx_CR_SI_Msk))

/**
  * @brief  使能I2C
  * @param  HANDLE : I2C 句柄指针，指向包含I2C配置、通信参数的结构体
  * @retval
  */
#define HAL_I2C_ENABLE(HANDLE)    ((HANDLE)->Instance->CR |= I2Cx_CR_EN_Msk)

/**
  * @brief  失能I2C
  * @param  HANDLE : I2C 句柄指针，指向包含I2C配置、通信参数的结构体
  * @retval
  */
#define HAL_I2C_DISABLE(HANDLE)   ((HANDLE)->Instance->CR &= ~(I2Cx_CR_EN_Msk | \
                                                               I2Cx_CR_AA_Msk |  \
                                                               I2Cx_CR_SI_Msk |  \
                                                               I2Cx_CR_STA_Msk))

/******************************************************************************/
/* Exported variables ('extern', definition in C source)                      */
/******************************************************************************/


/******************************************************************************/
/* Global function prototypes ('extern', definition in C source)              */
/******************************************************************************/
/* Base functions */
HAL_StatusTypeDef HAL_I2C_Master_SendStart(I2C_TypeDef *I2Cx);
HAL_StatusTypeDef HAL_I2C_Master_SendReStart(I2C_TypeDef *I2Cx);
HAL_StatusTypeDef HAL_I2C_Master_SendStop(I2C_TypeDef *I2Cx);
HAL_StatusTypeDef HAL_I2C_Master_SendByte(I2C_TypeDef *I2Cx, uint8_t TxByte);
uint8_t           HAL_I2C_Master_RecvByte(I2C_TypeDef *I2Cx, I2C_ResponseTypeDef AckOrNak);

void              HAL_I2C_Slave_Xfer_Init(I2C_TypeDef *I2Cx);
HAL_StatusTypeDef HAL_I2C_Slave_SendByte(I2C_TypeDef *I2Cx, uint8_t TxByte);
HAL_StatusTypeDef HAL_I2C_Slave_RecvByte(I2C_TypeDef *I2Cx, uint8_t *pRxByte, uint8_t AckOrNak);

/* Initialization and de-initialization functions */
HAL_StatusTypeDef HAL_I2C_Init(I2C_HandleTypeDef *hI2c);
HAL_StatusTypeDef HAL_I2C_DeInit(I2C_HandleTypeDef *hI2c);

/* Blocking mode: Polling */
HAL_StatusTypeDef HAL_I2C_Master_IsDeviceReady(I2C_HandleTypeDef *hI2c, uint16_t DevAddress, uint32_t Trials, uint32_t TimeOut);
HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hI2c, uint16_t DevAddress, uint8_t *pData, uint32_t Size, uint32_t TimeOut);
HAL_StatusTypeDef HAL_I2C_Master_Receive(I2C_HandleTypeDef *hI2c, uint16_t DevAddress, uint8_t *pData, uint32_t Size, uint32_t TimeOut);

HAL_StatusTypeDef HAL_I2C_Slave_WaitSelected(I2C_HandleTypeDef *hI2c, uint8_t *AccessAddr, I2C_XferModeTypeDef *XferMode, uint32_t TimeOut);
HAL_StatusTypeDef HAL_I2C_Slave_Transmit(I2C_HandleTypeDef *hI2c, uint8_t *pData, uint32_t Size, uint32_t TimeOut);
HAL_StatusTypeDef HAL_I2C_Slave_Receive(I2C_HandleTypeDef *hI2c, uint8_t *pData, uint32_t Size, uint32_t TimeOut);

/******* Non-Blocking mode: Interrupt */
HAL_StatusTypeDef HAL_I2C_Master_Transmit_IT(I2C_HandleTypeDef *hI2c, uint16_t DevAddress, uint8_t *pData, uint32_t Size);
HAL_StatusTypeDef HAL_I2C_Master_Transmit_IT_IsComplete(I2C_HandleTypeDef *hI2c);
HAL_StatusTypeDef HAL_I2C_Master_Receive_IT(I2C_HandleTypeDef *hI2c, uint16_t DevAddress, uint8_t *pData, uint32_t Size);
HAL_StatusTypeDef HAL_I2C_Master_Receive_IT_IsComplete(I2C_HandleTypeDef *hI2c);

HAL_StatusTypeDef HAL_I2C_Slave_Transmit_IT(I2C_HandleTypeDef *hI2c, uint8_t *pData, uint32_t Size);
HAL_StatusTypeDef HAL_I2C_Slave_Transmit_IT_IsComplete(I2C_HandleTypeDef *hI2c);
HAL_StatusTypeDef HAL_I2C_Slave_Receive_IT(I2C_HandleTypeDef *hI2c, uint8_t *pData, uint32_t Size);
HAL_StatusTypeDef HAL_I2C_Slave_Receive_IT_IsComplete(I2C_HandleTypeDef *hI2c);

void              HAL_I2C_IRQHandler(I2C_HandleTypeDef *hI2c);


#ifdef __cplusplus
}
#endif

#endif /* __SYM32L010_HAL_I2C_H */


/************************ (C) COPYRIGHT SIYIMicro *****END OF FILE*************/
